package com.brush.web.controller.user;


import cn.hutool.extra.spring.SpringUtil;
import com.brush.common.annotation.Log;
import com.brush.common.core.controller.BaseController;
import com.brush.common.core.domain.AjaxResult;
import com.brush.common.core.domain.R;
import com.brush.common.core.domain.entity.SysRole;
import com.brush.common.core.domain.entity.SysUser;
import com.brush.common.core.domain.resp.AdminUserResp;
import com.brush.common.core.domain.resp.DeptTreeResp;
import com.brush.common.core.domain.resp.SysRoleResp;
import com.brush.common.enums.BusinessType;
import com.brush.common.utils.SecurityUtils;
import com.brush.system.domain.req.sysdept.SysDeptReq;
import com.brush.system.domain.req.sysuser.*;
import com.brush.system.domain.resp.sysuser.SysUserResp;
import com.brush.system.service.SysDeptService;
import com.brush.system.service.SysPostService;
import com.brush.system.service.SysRoleService;
import com.brush.system.service.SysUserService;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

import static com.brush.common.utils.SecurityUtils.getUserId;

/**
 * 功能描述
 *
 * @author tonneyyy
 */
@Api(tags = "后台-用户管理api")
@RestController
@RequestMapping(value = "/admin/user")
public class SysUserController  extends BaseController {

    /**
     * 部门业务逻辑
     */
    @Autowired
    private SysDeptService sysDeptService;

    /**
     * 用户业务逻辑
     */
    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysPostService sysPostService;



    @PreAuthorize("@ss.hasPermi('system:dept:list')")
    @GetMapping(value = "/deptTree")
    @ApiOperation(value = "获取部门树")
    public R<List<DeptTreeResp>>  deptTree(){
        List<DeptTreeResp> treeResp= this.sysDeptService.allDeptTree(new SysDeptReq());
        return R.ok(treeResp);
    }


    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @ApiOperation(value = "分页查询")
    @GetMapping(value = "/list")
    public R<PageInfo<SysUserResp>> list(SysUserReq req) {
        PageInfo<SysUserResp> page = this.sysUserService.paginationQuery(req);
        return R.ok(page);
    }


    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @GetMapping(value = {  "/{userId}" })
    public R getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        this.sysUserService.checkUserDataScope(userId);

        R result=R.ok();
        List<SysRole> roles = this.sysRoleService.selectRoleAll();
        Map<String,Object> ajax=new HashMap<>();
        ajax.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        ajax.put("posts", this.sysPostService.list());
        if (Objects.nonNull(userId))
        {
            AdminUserResp sysUser = this.sysUserService.selectUserById(userId);
            ajax.put(AjaxResult.DATA_TAG, sysUser);
            ajax.put("postIds", this.sysPostService.selectPostListByUserId(userId));
            ajax.put("roleIds", sysUser.getRoles().stream().map(SysRoleResp::getRoleId).collect(Collectors.toList()));
        }
        return R.ok(ajax);
    }

    /**
     * 新增用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping
    public R add(@Validated @RequestBody SysUserAddReq user)
    {
        this.sysDeptService.checkDeptDataScope(user.getDeptId());
        this.sysRoleService.checkRoleDataScope(user.getRoleIds());
        if (!this.sysUserService.checkUserNameUnique(user.getUserName(),-1L))
        {
            return R.fail("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !this.sysUserService.checkPhoneUnique(user.getPhonenumber(),-1L))
        {
            return R.fail("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail()) && !this.sysUserService.checkEmailUnique(user.getEmail(),-1L))
        {
            return R.fail("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }

        boolean result=this.sysUserService.insertUser(user);
        return super.isSuccess(result);
    }

    /**
     * 修改用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public R edit(@Validated @RequestBody SysUserEditReq user)
    {
        this.sysUserService.checkUserAllowed(user.getUserId());
        this.sysUserService.checkUserDataScope(user.getUserId());
        this.sysDeptService.checkDeptDataScope(user.getDeptId());
        this.sysRoleService.checkRoleDataScope(user.getRoleIds());
        if (! this.sysUserService.checkUserNameUnique(user.getUserName(), user.getUserId()))
        {
            return R.fail("修改用户'" + user.getUserName() + "'失败，登录账号已存在");
        }
        else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !this.sysUserService.checkPhoneUnique(user.getPhonenumber(), user.getUserId()))
        {
            return R.fail("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        }
        else if (StringUtils.isNotEmpty(user.getEmail()) && !this.sysUserService.checkEmailUnique(user.getEmail(), user.getUserId()))
        {
            return R.fail("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }

        boolean result=this.sysUserService.updateUser(user);
        return super.isSuccess(result);
    }

    /**
     * 删除用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public R remove(@PathVariable Long[] userIds)
    {
        if (ArrayUtils.contains(userIds, getUserId()))
        {
            return R.fail("当前用户不能删除");
        }
        boolean result=this.sysUserService.deleteUserByIds(userIds);
        return super.isSuccess(result);
    }

    /**
     * 重置密码
     */
    @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public R resetPwd(@RequestBody SysUserChangePwdReq req)
    {
        this.sysUserService.checkUserAllowed(req.getUserId());
        this.sysUserService.checkUserDataScope(req.getUserId());
        boolean result=this.sysUserService.resetPwd(req);
        return super.isSuccess(result);
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public R changeStatus(@RequestBody SysUserChangeStatusReq req)
    {
        this.sysUserService.checkUserAllowed(req.getUserId());
        this.sysUserService.checkUserDataScope(req.getUserId());

        boolean result=this.sysUserService.changeStatus(req);

        return super.isSuccess(result);
    }

    /**
     * 根据用户编号获取授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @GetMapping("/authRole/{userId}")
    public R authRole(@PathVariable("userId") Long userId)
    {

        SysUser user = this.sysUserService.getById(userId);
        List<SysRole> roles = this.sysRoleService.selectRolesByUserId(userId);
        Map<String,Object> data=new HashMap<>();
        data.put("user", user);
        data.put("roles", SecurityUtils.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return R.ok(data);
    }

    /**
     * 用户授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PutMapping("/authRole")
    public R insertAuthRole(Long userId, Long[] roleIds)
    {
        this.sysUserService.checkUserDataScope(userId);
        this.sysRoleService.checkRoleDataScope(roleIds);
       boolean result= this.sysUserService.insertUserAuth(userId, roleIds);
        return super.isSuccess(result);
    }


}
